package com.qsw.refreshrecyclerview.RefreshRecyclerView.adapter;

import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * 支持页头及页尾操作的装饰Adapter
 */
public class HeaderFooterRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    // 用来存放底部和头部ViewId的集合
    private SparseArray<HFBean> mHeaderViews;
    private SparseArray<HFBean> mFooterViews;

    // 基本的头部类型开始位置  用于viewType
    private static int BASE_ITEM_TYPE_HEADER = 10000000;

    // 基本的底部类型开始位置  用于viewType
    private static int BASE_ITEM_TYPE_FOOTER = 20000000;

    // 列表的Adapter
    private RecyclerView.Adapter<RecyclerView.ViewHolder> mAdapter;

    public HeaderFooterRecyclerAdapter(RecyclerView.Adapter adapter) {
        this.mAdapter = adapter;
        mHeaderViews = new SparseArray<>();
        mFooterViews = new SparseArray<>();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // viewType即SparseArray的key
        if (isHeaderViewType(viewType)) {
            View headerView = mHeaderViews.get(viewType).view;
            if (headerView == null) {
                headerView = LayoutInflater.from(parent.getContext()).inflate(mHeaderViews.get(viewType).viewId, parent, false);
                mHeaderViews.get(viewType).view = headerView;
            }
            return createHeaderFooterViewHolder(headerView);
        }

        if (isFooterViewType(viewType)) {
            View footerView = mFooterViews.get(viewType).view;
            if (footerView == null) {
                footerView = LayoutInflater.from(parent.getContext()).inflate(mFooterViews.get(viewType).viewId, parent, false);
                mFooterViews.get(viewType).view = footerView;
            }
            return createHeaderFooterViewHolder(footerView);
        }

        return mAdapter.onCreateViewHolder(parent, viewType);
    }

    /**
     * 是不是底部类型
     */
    private boolean isFooterViewType(int viewType) {
        int index = mFooterViews.indexOfKey(viewType);
        return index >= 0;
    }

    /**
     * 创建头部或者底部的ViewHolder
     */
    private RecyclerView.ViewHolder createHeaderFooterViewHolder(View view) {
        return new RecyclerView.ViewHolder(view) {
        };
    }

    /**
     * 是不是头部类型
     */
    private boolean isHeaderViewType(int viewType) {
        int index = mHeaderViews.indexOfKey(viewType);
        return index >= 0;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (isHeaderPosition(position) || isFooterPosition(position)) {
            return;
        }

        // 计算一下位置
        position = position - mHeaderViews.size();
        mAdapter.onBindViewHolder(holder, position);
    }

    @Override
    public int getItemViewType(int position) {
        if (isHeaderPosition(position)) {
            // 直接返回position位置的key
            return mHeaderViews.keyAt(position);
        }

        if (isFooterPosition(position)) {
            // 直接返回position位置的key
            position = position - mHeaderViews.size() - mAdapter.getItemCount();
            return mFooterViews.keyAt(position);
        }

        // 返回列表Adapter的getItemViewType
        position = position - mHeaderViews.size();
        return mAdapter.getItemViewType(position);
    }

    RecyclerView.Adapter<RecyclerView.ViewHolder> getAdapter() {
        return mAdapter;
    }

    /**
     * 是不是底部位置
     */
    private boolean isFooterPosition(int position) {
        return position >= (mHeaderViews.size() + mAdapter.getItemCount());
    }

    /**
     * 是不是头部位置
     */
    private boolean isHeaderPosition(int position) {
        return position >= 0 && position < mHeaderViews.size();
    }

    @Override
    public int getItemCount() {
        // 条数三者相加 = 底部条数 + 头部条数 + Adapter的条数
        return mAdapter.getItemCount() + mHeaderViews.size() + mFooterViews.size();
    }

    /**
     * 获取内部嵌套的Adapter数据数量
     *
     * @return 内部嵌套的Adapter数据数量
     */
    public int getDataCount() {
        return mAdapter.getItemCount();
    }

    /**
     * 获取头部数量
     *
     * @return 头部数量
     */
    public int getHeaderCount() {
        return mHeaderViews.size();
    }

    /**
     * 获取尾部数量
     *
     * @return 尾部数量
     */
    public int getFooterCount() {
        return mFooterViews.size();
    }

    /**
     * 添加头部
     *
     * @param view 头部View
     */
    public void addHeaderView(View view) {
        addHeaderOrFooterView(view, true);
    }

    /**
     * 添加头部
     *
     * @param viewId 头部ViewId
     */
    public void addHeaderView(int viewId) {
        addHeaderOrFooterView(viewId, true);
    }

    /**
     * 添加底部
     *
     * @param view 底部View
     */
    public void addFooterView(View view) {
        addHeaderOrFooterView(view, false);
    }

    /**
     * 添加底部
     *
     * @param viewId 底部ViewId
     */
    public void addFooterView(int viewId) {
        addHeaderOrFooterView(viewId, false);
    }

    /**
     * 移除头部
     *
     * @param view 头部View
     */
    public void removeHeaderView(View view) {
        removeHeaderOrFooterView(view, true);
    }

    /**
     * 移除头部
     *
     * @param viewId 头部ViewId
     */
    public void removeHeaderView(int viewId) {
        removeHeaderOrFooterView(viewId, true);
    }

    /**
     * 移除所有头部
     */
    public void removeAllHeaderView() {
        removeAllHeaderOrFooterView(true);
    }

    /**
     * 移除底部
     *
     * @param view 底部View
     */
    public void removeFooterView(View view) {
        removeHeaderOrFooterView(view, false);
    }


    /**
     * 移除底部
     *
     * @param viewId 底部ViewId
     */
    public void removeFooterView(int viewId) {
        removeHeaderOrFooterView(viewId, false);
    }

    /**
     * 移除所有底部
     */
    public void removeAllFooterView() {
        removeAllHeaderOrFooterView(false);
    }

    /**
     * 添加头部或底部
     *
     * @param view   要添加的View
     * @param header true：头部；false：底部
     */
    private void addHeaderOrFooterView(View view, boolean header) {
        if (view == null) {
            return;
        }
        if (header) {
            mHeaderViews.put(BASE_ITEM_TYPE_HEADER++, new HFBean(view));
        } else {
            mFooterViews.put(BASE_ITEM_TYPE_FOOTER++, new HFBean(view));
        }
        notifyDataSetChanged();
    }

    /**
     * 添加头部或底部
     *
     * @param viewId 要添加的ViewId
     * @param header true：头部；false：底部
     */
    private void addHeaderOrFooterView(int viewId, boolean header) {
        if (viewId < 0) {
            return;
        }
        if (header) {
            mHeaderViews.put(BASE_ITEM_TYPE_HEADER++, new HFBean(viewId));
        } else {
            mFooterViews.put(BASE_ITEM_TYPE_FOOTER++, new HFBean(viewId));
        }
        notifyDataSetChanged();
    }

    /**
     * 移除头部或底部
     *
     * @param view   要移除的View
     * @param header true：头部；false：底部
     */
    private void removeHeaderOrFooterView(View view, boolean header) {
        if (view == null) {
            return;
        }
        SparseArray<HFBean> sparseArray = header ? mHeaderViews : mFooterViews;
        for (int i = 0; i < sparseArray.size(); i++) {
            if (sparseArray.valueAt(i).view != null && sparseArray.valueAt(i).view == view) {
                sparseArray.removeAt(i);
            }
        }
        notifyDataSetChanged();
    }

    /**
     * 移除头部或底部
     *
     * @param viewId 要移除的ViewId
     * @param header true：头部；false：底部
     */
    private void removeHeaderOrFooterView(int viewId, boolean header) {
        if (viewId < 0) {
            return;
        }
        SparseArray<HFBean> sparseArray = header ? mHeaderViews : mFooterViews;
        for (int i = 0; i < sparseArray.size(); i++) {
            if (sparseArray.valueAt(i).viewId == viewId) {
                sparseArray.removeAt(i);
            }
        }
        notifyDataSetChanged();
    }

    /**
     * 移除所有头部或底部
     *
     * @param header true：头部；false：底部
     */
    private void removeAllHeaderOrFooterView(boolean header) {
        (header ? mHeaderViews : mFooterViews).clear();
        notifyDataSetChanged();
    }

    /**
     * 解决GridLayoutManager添加头部和底部不占用一行的问题
     *
     * @param recycler RecyclerView
     */
    public void adjustSpanSize(RecyclerView recycler) {
        if (recycler.getLayoutManager() instanceof GridLayoutManager) {
            final GridLayoutManager layoutManager = (GridLayoutManager) recycler.getLayoutManager();
            layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    boolean isHeaderOrFooter = isHeaderPosition(position) || isFooterPosition(position);
                    return isHeaderOrFooter ? layoutManager.getSpanCount() : 1;
                }
            });
        }
    }

    /**
     * 页头页尾封装
     */
    private class HFBean {
        private int viewId = -1;
        private View view = null;

        HFBean(int viewId) {
            this.viewId = viewId;
        }

        HFBean(View view) {
            this.view = view;
        }
    }
}